import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:series_play/bean/local_video_data.dart';
import 'package:series_play/comm/base/base_list_controller.dart';

import '../../../utils/log.dart';

/// 该控制器控制播放器的
abstract class BaseFeedVideoController
    extends BaseListController<LocalVideoData>
    with WidgetsBindingObserver {
  late final players = HashMap<int, Player>();
  late final controllers = HashMap<int, VideoController>();

  /// 播放进度
  var positions = <int, Rx<Duration>>{}.obs;

  /// 总时长
  var durations = <int, Rx<Duration>>{}.obs;

  /// 是否是自动暂停的
  bool _wasAutoPaused = false;

  /// 用户是否主动暂停过
  var userPaused = false.obs;

  /// 当前播放下标
  var _currentIndex = 0;

  /// 当前页面是否完全可见 前台时更新
  ///
  /// 由主页面更新
  var isPageFullyVisible = true.obs;

  /// 监听页面可见状态变化
  Worker? _pageVisibleWorker;

  @override
  void onInit() {
    super.onInit();
    WidgetsBinding.instance.addObserver(this);
    // 监控页面变化
    _pageVisibleWorker = ever(isPageFullyVisible, (val) {
      if (val) {
        _autoPlay();
      } else {
        _autoPause();
      }
    });
  }

  /// 页面切换时切换视频
  Future<void> onPageChanged(int i) async {
    Log.e('页面切换');

    _currentIndex = i;

    if (userPaused.value) {
      userPaused.value = false;
    }

    // 播放当前页面的视频。
    players[i]?.play();

    // step:1 处理不可见且不与当前页面相邻的页面的[Player]和[VideoController]。
    players.removeWhere((page, player) {
      final remove = ![i, i - 1, i + 1].contains(page);
      if (remove) {
        player.dispose();
      }
      return remove;
    });
    controllers.removeWhere((page, controller) {
      final remove = ![i, i - 1, i + 1].contains(page);
      return remove;
    });

    // step:2 暂停其他页面的视频。
    for (final e in players.entries) {
      if (e.key != i) {
        e.value.pause();
        // 归位
        e.value.seek(Duration.zero);
      }
    }

    // step:3 为下一页和上一页创建[Player]和[VideoController]。很明显，当前页面的[Player] & [VideoController]将已经存在，仍然冗余检查它
    if (!players.containsKey(i)) {
      createPlayer(i);
    }
    if (!players.containsKey(i + 1)) {
      createPlayer(i + 1);
    }
    if (!players.containsKey(i - 1)) {
      createPlayer(i - 1);
    }
  }

  // 只需创建一个新的[Player]和[VideoController]，加载视频并保存它。
  Future<void> createPlayer(int page) async {
    if (page < 0 || page >= dataList.length) {
      return;
    }
    final player = Player();
    final controller = VideoController(
      player,
      configuration: VideoControllerConfiguration(
        enableHardwareAcceleration: false,
      ),
    );
    await player.setPlaylistMode(PlaylistMode.loop);
    await player.open(Media(dataList[page].localUrl!), play: false);
    players[page] = player;
    controllers[page] = controller;
    _bindListener(player, page);
  }

  Future<void> createPlayer2(int page, String url) async {
    final player = Player();
    final controller = VideoController(player);
    await player.setPlaylistMode(PlaylistMode.loop);
    await player.open(Media(url), play: false);
    players[page] = player;
    controllers[page] = controller;
    _bindListener(player, page);
  }

  void _bindListener(Player player, int page) {
    // 初始化！
    positions[page] = Duration.zero.obs;
    durations[page] = Duration.zero.obs;

    // 绑定监听
    player.stream.position.listen((pos) {
      positions[page]?.value = pos;
    });

    player.stream.duration.listen((d) {
      durations[page]?.value = d;
    });
  }

  /// 用户点击播放/暂停
  Future<void> onTogglePlay(int page) async {
    if (!players.containsKey(page)) {
      return;
    }
    final state = players[page]!.state;
    if (state.playing) {
      userPaused.value = true;
      players[page]!.pause();
    } else {
      userPaused.value = false;
      players[page]!.play();
    }
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // 不在当前页面不处理
    if (!isPageFullyVisible.value) {
      return;
    }
    switch (state) {
      case AppLifecycleState.paused: // App进入后台
        Log.wtf("进入后台");
        _autoPause();
        break;
      case AppLifecycleState.resumed: // 回到前台
        Log.wtf("返回前台");
        _autoPlay();
        break;
      default:
        break;
    }
  }

  void _autoPause() {
    final player = players[_currentIndex];
    // 正在播放中的话要暂停掉
    if (player != null && player.state.playing) {
      _wasAutoPaused = true;
      player.pause();
    }
  }

  void _autoPlay() {
    final player = players[_currentIndex];
    // 如果时自动暂停不是手动暂停的话要回复播放
    if (player != null && _wasAutoPaused && !userPaused.value) {
      _wasAutoPaused = false;
      player.play();
    }
  }

  // 切换播放状态
  void switchPlay() {
    final player = players[_currentIndex];

    if (player == null) {
      return;
    }

    if (player.state.playing) {
      player.pause();
      userPaused.value = true;
    } else {
      player.play();
      userPaused.value = false;
    }
  }

  @override
  void onClose() {
    for (final player in players.values) {
      player.dispose();
    }
    _pageVisibleWorker?.dispose();
    WidgetsBinding.instance.removeObserver(this);
    super.onClose();
  }
}
